#pragma once
#include"Sock.hpp"
#include<sys/epoll.h>

#define PORT 8081
using namespace std;
class Epoll{
    private:
        int listen_sock;
        int port;
        int epfd;
    public:
        Epoll(int _port=PORT):port(_port),listen_sock(-1),epfd(-1)
        {}
        void Initserver()
        {
            Socket::Sock(listen_sock);
            Socket::Bind(listen_sock,port);
            Socket::Listen(listen_sock);

            epfd=epoll_create(256);
            if(epfd<0){
                cerr<<"epoll_create error"<<endl;
                exit(4);
            }
            cout<<"epoll_create success: "<<epfd<<endl;  
        }
        void EpollADD(int sock,uint32_t event){
            struct epoll_event ev;
            ev.events=0;
            ev.events|=event;
            ev.data.fd=sock;
            if(epoll_ctl(epfd,EPOLL_CTL_ADD,sock,&ev)<0){
                cerr<<"epoll_ctl_add error: "<<sock<<endl;
            }
        }
        void EpollDEL(int sock){
            if(epoll_ctl(epfd,EPOLL_CTL_DEL,sock,nullptr)<0){
                cerr<<"epoll_ctl_del error: "<<sock<<endl;
            }
        }
        void Loop(){
            EpollADD(listen_sock,EPOLLIN);
            struct epoll_event env[128];
            int _max=128;
            int timeout=-1;
            for(;;){
                int num=epoll_wait(epfd,env,_max,timeout);
                if(num>0){
                    for(int i=0;i<num;i++){
                        if(env[i].events & EPOLLIN){
                            if(env[i].data.fd==listen_sock){
                                struct sockaddr_in oth;
                                socklen_t len=sizeof(oth);
                                int sock=accept(listen_sock,(struct sockaddr*)&oth,&len);
                                if(sock<0){
                                    cerr<<"accept error"<<endl;
                                    continue;
                                }
                                else{
                                    EpollADD(sock,EPOLLIN);
                                }
                            }
                            else{
                                char buffer[1024];
                                ssize_t s=recv(env[i].data.fd,buffer,1023,0);
                                if(s>0){
                                    buffer[s]=0;
                                    cout<<"-># "<<buffer<<endl;
                                }
                                else{
                                    cout<<"client...."<<endl;
                                    close(env[i].data.fd);
                                    EpollDEL(env[i].data.fd);
                                }
                            }
                        }
                        else if(env[i].events&EPOLLOUT){

                        }
                        else{

                        }
                    }
                }
                else if(num==0){
                    cout<<timeout<<"..."<<endl;
                }
                else{
                    cout << "epoll error" <<endl;
                }
            }
        }
        ~Epoll(){
            if(listen_sock>=0)
                close(listen_sock);
            if(epfd>=0)
                close(epfd);
        }

};